package com.joinway.framework.admin.core.service.file;

import java.io.File;
import java.util.Calendar;
import java.util.UUID;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;

import com.joinway.framework.bean.type.Server;
import com.joinway.framework.core.repository.SystemConfigRepository;
import com.joinway.framework.core.utils.FrameworkHelper;

/**
 * 用于管理文件存储
 * @author Administrator
 *
 */
@Deprecated
@Service
public class FileManager implements ApplicationContextAware {

	private final static Logger log = LoggerFactory.getLogger(FileManager.class);
	
//	private final static String APP_DIR_PREFFIX = "app-";
	private final static String APP_DIR_PREFFIX = "";
	
	static ApplicationContext ctx;
	
	static SystemConfigRepository repository;
	
	public static String getAvailableName(){
		return getAvailableName(DateFormatUtils.format(Calendar.getInstance(), "yyyyMMdd"));
	}

	public static String getAvailableName(String prefix){
		String id = StringUtils.isBlank(prefix) ? DateFormatUtils.format(Calendar.getInstance(), "yyyyMMdd") : StringUtils.trimToEmpty(prefix);
		return id + "-" + StringUtils.split(UUID.randomUUID().toString(), "-")[0];
	}
	
	public static String getFileRoot(Server server) throws Exception {
		return getLocalPath("", server);
	}
	
	/**
	 * 获得文件要保存的本地路径
	 * @param path 相对于根目录的路径，起到命名空间的作用，同一类别的文件放到用一个path下
	 * @param server 服务器类型
	 * @return 本地绝对路径
	 * @throws Exception
	 */
	public static String getLocalPath(String path, Server server) throws Exception {
		String localPath;

		if(server == Server.App){
			localPath = FrameworkHelper.getAppRootLocalPath() + repository.getStringValue(SystemConfigRepository.JspRoot) + "/" + path;
		}else{
			localPath = repository.getStringValue(SystemConfigRepository.WebRootPath) + "/" + APP_DIR_PREFFIX + FilenameUtils.getBaseName(FrameworkHelper.getAppNamePath()) + "/" + path;
		}

		return localPath;
	}

	/**
	 * 获得文件要保存的本地路径
	 * @param path 相对于根目录的路径，起到命名空间的作用，同一类别的文件放到用一个path下
	 * @param server 服务器类型
	 * @param request 
	 * @return 本地绝对路径
	 * @throws Exception
	 */
	public static String getLocalPath(String path, Server server, HttpServletRequest request) throws Exception {
		String localPath;

		if(server == Server.App){
			localPath = request.getServletContext().getRealPath("/") + repository.getStringValue(SystemConfigRepository.JspRoot) + "/" + path;
		}else{
			localPath = repository.getStringValue(SystemConfigRepository.WebRootPath) + "/" + APP_DIR_PREFFIX + FilenameUtils.getBaseName(request.getContextPath()) + "/" + path;
		}

		return localPath;
	}

	/**
	 * 保存文件到磁盘
	 * @param path 文件保存位置，相对于web/app server根目录的位置
	 * @param fileName 文件名称(包括后缀)
	 * @param server 服务器类型
	 * @param port	访问端口
	 * @param callback 保存文件的回调接口
	 * @param context 文件上下文
	 * @return 客户端访问的url地址
	 */
	public static<T> String save(String path, String fileName, Server server, int port, IFileRepository<T> callback, T context) throws Exception{
		String localPath = getLocalPath(path, server);
		String url = getUrl(path, fileName, server, port);
		
		FileUtils.forceMkdir(new File(localPath));
		
		callback.save(localPath + "/" + fileName, context);
		log.info("saved file to {}", localPath + "/" + fileName);
		
		return url;		
	}
	
	public static<T> String save(String path, String fileName, Server server, int port, IFileRepository<T> callback) throws Exception{
		return save(path, fileName, server, port, callback, null);
	}
	
	public static<T> String save(String path, String fileName, Server server, IFileRepository<T> callback, T context) throws Exception{
		return save(path, fileName, server, 0, callback, context);
	}
	
	/**
	 * 保存文件到磁盘
	 * @param path 文件保存位置，相对于web/app server根目录的位置
	 * @param fileName 文件名称(包括后缀)
	 * @param server 服务器类型
	 * @param callback 保存文件的回调接口
	 * @return 客户端访问的url地址
	 */
	public static<T> String save(String path, String fileName, Server server, IFileRepository<T> callback) throws Exception {
		return save(path, fileName, server, 0, callback, null);
	}
	
	/**
	 * 查看文件是否存在
	 * @param path 文件保存位置，相对于web/app server根目录的位置
	 * @param fileName 文件名称(包括后缀)
	 * @param server 服务器类型
	 * @return true - 存在, false - 不存在
	 * @throws Exception
	 */
	public static boolean exists(String path, String fileName, Server server) throws Exception{
		String localPath = getLocalPath(path, server);
		File file = new File(localPath + "/" + fileName);
		return file.exists();
	}
	
	static String getUrl(String path, String fileName, Server server) throws Exception {
		return getUrl(path, fileName, server);
	}
	
	static String getUrl(String path, String fileName, Server server, int port) throws Exception {
		String fname = FilenameUtils.getBaseName(fileName);
		String url;
		
		if(server == Server.App){
			url = FrameworkHelper.getAppServerRoot() + path + "/" + fname + repository.getStringValue(SystemConfigRepository.PageRequestSuffix);
		}else{
			url = FrameworkHelper.getWebServerRoot(port) + APP_DIR_PREFFIX + FilenameUtils.getBaseName(FrameworkHelper.getAppNamePath()) + "/" + path + "/" + fileName;
		}
		
		return url;
	}
	
	@PostConstruct
	public void init(){
		repository = ctx.getBean(SystemConfigRepository.class);
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		ctx = applicationContext;
	}
}
